package com.stuffthathappens.concurrency;

import java.util.Queue;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.BlockingQueue;

/**
 * @author Eric Burke
 */
public class DonutProducer implements Runnable {
    private final String producerName;
    private final BlockingQueue<Donut> queue;
    private final Random rand = new Random();
    private final TimeUnit delayUnit;
    private final long delay;

    public DonutProducer(String producerName, BlockingQueue<Donut> queue,
                         TimeUnit delayUnit, long delay) {
        this.producerName = producerName;
        this.queue = queue;
        this.delayUnit = delayUnit;
        this.delay = delay;
    }

    public void run() {
        try {
            while (true) {
                delayUnit.sleep(delay);
                final Donut donut = makeDonut();

                // notes:
                // - offer won't block, but will return false if the queue is full
                // - add(...) is also possible, but may throw an exception
                // boolean success = queue.offer(donut);

                // this will block if the queue is full
                queue.put(donut);

                System.out.format("%s added a %s donut.%n", producerName, donut.getType());
            }
        } catch (InterruptedException e) {
            // let this Runnable end gracefully
            System.out.println(producerName + " is interrupted.");
        }
    }

    private Donut makeDonut() {
        final Donut.Type[] allTypes = Donut.Type.values();

        return new Donut(producerName, allTypes[rand.nextInt(allTypes.length)]);
    }
}
